/* eslint-disable block-scoped-var */
import { omit, keys, toNumber, isNaN, isArray } from 'lodash'
import utils from '@/utils'
import { Base64 } from 'js-base64'
import dayjs from 'dayjs'
import { Divider } from 'element-ui'
/**
 * 解析token
 * @param {keyName:'键名'}
 */
export function parseToken(token) {
    // let token = uni.getStorageSync('token')
    // utils.db.dbSet({ dbName, path, value, user })
    let dataBase64String = token.split('.')[1]
    //解析base64
    let tempStr = Base64.decode(dataBase64String)
    if (typeof tempStr === 'string') {
        tempStr = JSON.parse(tempStr).sub
    }
    let userInfo = JSON.parse(tempStr)
    console.log(userInfo)
    // if (keyName) {
    //     return userInfo[keyName]
    // }
    return userInfo
}
/**
 * @description 将单词转换为首字母大写
 * @param {String} word 需要转化的单词
 */
export function wordUpper(word) {
    return word.replace(word[0], word[0].toUpperCase())
}

/**
 * @description 在 source 中是否至少有一个 need 中的项目
 * @param {Array} source 数据源
 * @param {Array} need 需要存在的项目
 */
export function oneOf(source, need) {
    if (isArray(need)) {
        return need.reduce(
            (result, item) => result || source.indexOf(item) >= 0,
            false
        )
    }
    return source.indexOf(need) >= 0
}

/**
 * @description 在 source 包括 need
 * @param {Array} source 数据源
 * @param {Array} need 需要存在的项目
 */
export function allIn(source, need) {
    if (isArray(need)) {
        return need.reduce(
            (result, item) => !(result === false || source.indexOf(item) < 0),
            true
        )
    }
    return source.indexOf(need) >= 0
}

/**
 * @description 检查一个对象是否有子元素
 * @param {Object} item 检查的对象
 * @param {String} keyname 子元素的 keyname
 */
export function hasChildren(item = {}, keyname = 'sub') {
    if (isArray(item[keyname])) {
        // console.log(
        //     item[keyname],
        //     item[keyname].every(e => e.is_hidden !== 1)
        // )
    }
    return item[keyname] && isArray(item[keyname]) && item[keyname].length > 0
}

/**
 * 比较两个数组是否值一样 忽略顺序
 * @param {Array} array1 比较的数组
 * @param {Array} array2 比较的数组
 */
export function isIdenticalArray(array1, array2) {
    let result = true
    if (array1.length !== array2.length) {
        result = false
    } else {
        array1.forEach(item => {
            if (array2.indexOf(item) < 0) {
                result = false
            }
        })
    }
    return result
}

/**
 * 比较两个对象是否值一样 忽略顺序
 * @param {Array} array1 比较的对象
 * @param {Array} array2 比较的对象
 */
export function isIdenticalObject(object1, object2) {
    let result = true
    const keys1 = keys(object1)
    const keys2 = keys(object2)
    if (!isIdenticalArray(keys1, keys2)) {
        result = false
    } else {
        keys1.forEach(keyName => {
            if (object1[keyName] !== object2[keyName]) {
                result = false
            }
        })
    }
    return result
}

/**
 * @description 合法的用户名
 * @description 3~10个字符 只能是字母 数字 下划线
 * @param {String} value 需要校验的数据
 */
export function isLegalUsername(value) {
    return /^[A-Za-z_0-9]{3,12}$/.test(value)
}
/**
 * @description 同 isLegalUsername
 * @description 适用于表单校验
 */
export function isLegalUsernameValidator(rule, value, callback) {
    callback(
        value === '' || isLegalUsername(value)
            ? undefined
            : new Error('3~10个字符 只能是字母 数字 下划线')
    )
}

/**
 * @description 合法的密码
 * @description 6-15个字符 至少包括大写 小写 下划线 数字两种
 * @param {String} value 需要校验的数据
 */
export function isLegalPassword(value) {
    if (value.length < 6 || value.length > 16) {
        return false
    }
    // 如果包含上述四种以外的字符 false
    if (/[^A-Za-z_0-9]/.test(value)) {
        return false
    }
    // 如果全为大写、小写、下划线、数字, false
    if (/(^[a-z]+$)|(^[A-Z]+$)|(^_+$)|(^\d+$)/g.test(value)) {
        return false
    }
    return true
}
/**
 * @description 同 isLegalPassword
 * @description 适用于表单校验
 */
export function isLegalPasswordValidator(rule, value, callback) {
    callback(
        value === '' || isLegalPassword(value)
            ? undefined
            : new Error('6-15个字符，至少包括大写、小写、下划线、数字两种')
    )
}

/**
 * @description 合法的手机号码
 * @param {String} value 需要校验的数据
 */
export function isLegalMobilePhone(value) {
    return /^1[3-9]\d{9}$/.test(value)
}
/**
 * @description 同 isLegalMobilePhone
 * @description 适用于表单校验
 */
export function isLegalMobilePhoneValidator(rule, value, callback) {
    callback(
        value === '' || isLegalMobilePhone(value)
            ? undefined
            : new Error('手机号码格式不正确')
    )
}

/**
 * @description 合法的邮箱
 * @description 名称允许汉字、字母、数字，域名只允许英文域名
 * @param {String} value 需要校验的数据
 */
export function isLegalEmail(value) {
    return /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(
        value
    )
}

/**
 * @description 同 isLegalEmail
 * @description 适用于表单校验
 */
export function isLegalEmailValidator(rule, value, callback) {
    callback(
        value === '' || isLegalEmail(value)
            ? undefined
            : new Error('邮箱格式不正确')
    )
}

/**
 * @description 将树形数据扁平化 输出数组格式
 * @param {Object} config {Array} data 树形数据
 * @param {Object} config {String} keyChildren 子节点字段名
 * @param {Object} config {Boolean} includeChildren 输出的数据中是否包含子节点数据
 */
export function flatTreeToArray({
    data = [],
    keyChildren = 'sub',
    includeChildren = false
} = {}) {
    function maker(result, item) {
        result.push(includeChildren ? item : omit(item, [keyChildren]))
        if (hasChildren(item, keyChildren)) {
            result = result.concat(item[keyChildren].reduce(maker, []))
        }
        return result
    }
    return data.reduce(maker, [])
}

/**
 * @description 将树形数据扁平化 输出对象格式
 * @param {Object} config {Array} data 树形数据
 * @param {Object} config {String} keyChildren 子节点字段名
 * @param {Object} config {String} keyId 唯一 id 字段名
 * @param {Object} config {Boolean} includeChildren 输出的数据中是否包含子节点数据
 */
export function flatTreeToObject({
    data = [],
    keyChildren = 'sub',
    keyId = 'id',
    includeChildren = false
} = {}) {
    function maker(result, item) {
        result[item[keyId]] = includeChildren ? item : omit(item, [keyChildren])
        if (hasChildren(item, keyChildren)) {
            Object.assign(result, item[keyChildren].reduce(maker, {}))
        }
        return result
    }
    return data.reduce(maker, {})
}

/**
 * @description 传入一个值 返回处理成数字的结果
 * @param {Any} value 需要处理的值
 */
export function getNumberOrZero(value) {
    const result = toNumber(value)
    return isNaN(result) ? 0 : result
}
// 是否url地址
export const isURL = s => {
    return /^http[s]?:\/\/.*/.test(s)
}
// 获取url参数
export const getQueryString = name => {
    const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
    const search = window.location.search.split('?')[1] || ''
    const r = search.match(reg) || []
    return r[2]
}
// 动态引入js
export const injectScript = src => {
    const s = document.createElement('script')
    s.type = 'text/javascript'
    s.async = true
    s.src = src
    const t = document.getElementsByTagName('script')[0]
    t.parentNode.insertBefore(s, t)
}
// 根据url地址下载
export const download = url => {
    var isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1
    var isSafari = navigator.userAgent.toLowerCase().indexOf('safari') > -1
    if (isChrome || isSafari) {
        var link = document.createElement('a')
        link.href = url
        if (link.download !== undefined) {
            var fileName = url.substring(url.lastIndexOf('/') + 1, url.length)
            link.download = fileName
        }
        if (document.createEvent) {
            var e = document.createEvent('MouseEvents')
            e.initEvent('click', true, true)
            link.dispatchEvent(e)
            return true
        }
    }
    if (url.indexOf('?') === -1) {
        url += '?download'
    }
    window.open(url, '_self')
    return true
}
// 获取滚动的坐标
export const getScrollPosition = (el = window) => ({
    x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
    y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
})
// 滚动到顶部
export const scrollToTop = () => {
    const c = document.documentElement.scrollTop || document.body.scrollTop
    if (c > 0) {
        window.requestAnimationFrame(scrollToTop)
        window.scrollTo(0, c - c / 8)
    }
}
// el是否在视口范围内
export const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
    const { top, left, bottom, right } = el.getBoundingClientRect()
    const { innerHeight, innerWidth } = window
    return partiallyVisible
        ? ((top > 0 && top < innerHeight) ||
              (bottom > 0 && bottom < innerHeight)) &&
              ((left > 0 && left < innerWidth) ||
                  (right > 0 && right < innerWidth))
        : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth
}
// eslint-disable-next-line complexity
// 将数字转换为大写金额
export const changeToChinese = Num => {
    //判断如果传递进来的不是字符的话转换为字符
    if (typeof Num === 'number') {
        Num = new String(Num)
    }
    Num = Num.replace(/,/g, '') //替换tomoney()中的“,”
    Num = Num.replace(/ /g, '') //替换tomoney()中的空格
    Num = Num.replace(/￥/g, '') //替换掉可能出现的￥字符
    if (isNaN(Num)) {
        //验证输入的字符是否为数字
        //alert("请检查小写金额是否正确");
        return ''
    }
    //字符处理完毕后开始转换，采用前后两部分分别转换
    var part = String(Num).split('.')
    // eslint-disable-next-line block-scoped-var
    var newchar = ''
    //小数点前进行转化
    for (var i = part[0].length - 1; i >= 0; i--) {
        if (part[0].length > 10) {
            return ''
            //若数量超过拾亿单位，提示
        }
        var tmpnewchar = ''
        var perchar = part[0].charAt(i)
        switch (perchar) {
            case '0':
                tmpnewchar = '零' + tmpnewchar
                break
            case '1':
                tmpnewchar = '壹' + tmpnewchar
                break
            case '2':
                tmpnewchar = '贰' + tmpnewchar
                break
            case '3':
                tmpnewchar = '叁' + tmpnewchar
                break
            case '4':
                tmpnewchar = '肆' + tmpnewchar
                break
            case '5':
                tmpnewchar = '伍' + tmpnewchar
                break
            case '6':
                tmpnewchar = '陆' + tmpnewchar
                break
            case '7':
                tmpnewchar = '柒' + tmpnewchar
                break
            case '8':
                tmpnewchar = '捌' + tmpnewchar
                break
            case '9':
                tmpnewchar = '玖' + tmpnewchar
                break
        }
        switch (part[0].length - i - 1) {
            case 0:
                tmpnewchar = tmpnewchar + '元'
                break
            case 1:
                if (perchar !== 0) {
                    tmpnewchar = tmpnewchar + '拾'
                }
                break
            case 2:
                if (perchar !== 0) {
                    tmpnewchar = tmpnewchar + '佰'
                }
                break
            case 3:
                if (perchar !== 0) {
                    tmpnewchar = tmpnewchar + '仟'
                }
                break
            case 4:
                tmpnewchar = tmpnewchar + '万'
                break
            case 5:
                if (perchar !== 0) {
                    tmpnewchar = tmpnewchar + '拾'
                }
                break
            case 6:
                if (perchar !== 0) {
                    tmpnewchar = tmpnewchar + '佰'
                }
                break
            case 7:
                if (perchar !== 0) {
                    tmpnewchar = tmpnewchar + '仟'
                }
                break
            case 8:
                tmpnewchar = tmpnewchar + '亿'
                break
            case 9:
                tmpnewchar = tmpnewchar + '拾'
                break
        }
        // eslint-disable-next-line no-redeclare
        var newchar = tmpnewchar + newchar
    }
    //小数点之后进行转化
    if (Num.indexOf('.') !== -1) {
        if (part[1].length > 2) {
            // alert("小数点之后只能保留两位,系统将自动截断");
            part[1] = part[1].substr(0, 2)
        }
        for (let i = 0; i < part[1].length; i++) {
            tmpnewchar = ''
            perchar = part[1].charAt(i)
            switch (perchar) {
                case '0':
                    tmpnewchar = '零' + tmpnewchar
                    break
                case '1':
                    tmpnewchar = '壹' + tmpnewchar
                    break
                case '2':
                    tmpnewchar = '贰' + tmpnewchar
                    break
                case '3':
                    tmpnewchar = '叁' + tmpnewchar
                    break
                case '4':
                    tmpnewchar = '肆' + tmpnewchar
                    break
                case '5':
                    tmpnewchar = '伍' + tmpnewchar
                    break
                case '6':
                    tmpnewchar = '陆' + tmpnewchar
                    break
                case '7':
                    tmpnewchar = '柒' + tmpnewchar
                    break
                case '8':
                    tmpnewchar = '捌' + tmpnewchar
                    break
                case '9':
                    tmpnewchar = '玖' + tmpnewchar
                    break
            }
            if (i === 0) {
                tmpnewchar = tmpnewchar + '角'
            }
            if (i === 1) {
                tmpnewchar = tmpnewchar + '分'
            }
            newchar = newchar + tmpnewchar
        }
    }
    //替换所有无用汉字
    while (newchar.search('零零') !== -1) {
        newchar = newchar.replace('零零', '零')
    }
    newchar = newchar.replace('零亿', '亿')
    newchar = newchar.replace('亿万', '亿')
    newchar = newchar.replace('零万', '万')
    newchar = newchar.replace('零元', '元')
    newchar = newchar.replace('零角', '')
    newchar = newchar.replace('零分', '')
    if (newchar.charAt(newchar.length - 1) === '元') {
        newchar = newchar + '整'
    }
    return newchar
}
// 数组排序
export const sort = (arr, type = 1) => {
    return arr.sort((a, b) => {
        switch (type) {
            case 1:
                return a - b
            case 2:
                return b - a
            case 3:
                return Math.random() - 0.5
            default:
                return arr
        }
    })
}
// 求两个集合的并集
export const union = (a, b) => {
    var newArr = a.concat(b)
    return this.unique(newArr)
}
// 求两个集合的交集
export const intersect = (a, b) => {
    var _this = this
    a = this.unique(a)
    return this.map(a, function(o) {
        return _this.contains(b, o) ? o : null
    })
}
// 删除其中一个元素
export const remove = (arr, ele) => {
    var index = arr.indexOf(ele)
    if (index > -1) {
        arr.splice(index, 1)
    }
    return arr
}
// 最大值
export const max = arr => {
    return Math.max.apply(null, arr)
}
// 最小值
export const min = arr => {
    return Math.min.apply(null, arr)
}
// 求和
export const sum = arr => {
    return arr.reduce((pre, cur) => {
        return pre + cur
    })
}
// 平均值
export const average = arr => {
    return this.sum(arr) / arr.length
}
// 字符转换，type: 1:首字母大写 2：首字母小写 3：大小写转换 4：全部大写 5：全部小写
export const changeCase = (str, type) => {
    type = type || 4
    switch (type) {
        case 1:
            return str.replace(/\b\w+\b/g, function(word) {
                return (
                    word.substring(0, 1).toUpperCase() +
                    word.substring(1).toLowerCase()
                )
            })
        case 2:
            return str.replace(/\b\w+\b/g, function(word) {
                return (
                    word.substring(0, 1).toLowerCase() +
                    word.substring(1).toUpperCase()
                )
            })
        case 3:
            return str
                .split('')
                .map(function(word) {
                    if (/[a-z]/.test(word)) {
                        return word.toUpperCase()
                    } else {
                        return word.toLowerCase()
                    }
                })
                .join('')
        case 4:
            return str.toUpperCase()
        case 5:
            return str.toLowerCase()
        default:
            return str
    }
}
// 检测密码强度
export const checkPwd = str => {
    var Lv = 0
    if (str.length < 6) {
        return Lv
    }
    if (/[0-9]/.test(str)) {
        Lv++
    }
    if (/[a-z]/.test(str)) {
        Lv++
    }
    if (/[A-Z]/.test(str)) {
        Lv++
    }
    if (/[\.|-|_]/.test(str)) {
        Lv++
    }
    return Lv
}
// 函数节流器
export const debouncer = (fn, time, interval = 200) => {
    if (time - (window.debounceTimestamp || 0) > interval) {
        fn && fn()
        window.debounceTimestamp = time
    }
}
//在字符串中插入新字符串
export const insertStr = (soure, index, newStr) => {
    var str = soure.slice(0, index) + newStr + soure.slice(index)
    return str
}
// 判断两个对象是否键值相同
export const isObjectEqual = (a, b) => {
    var aProps = Object.getOwnPropertyNames(a)
    var bProps = Object.getOwnPropertyNames(b)

    if (aProps.length !== bProps.length) {
        return false
    }

    for (var i = 0; i < aProps.length; i++) {
        var propName = aProps[i]

        if (a[propName] !== b[propName]) {
            return false
        }
    }
    return true
}
// 追加url参数
export const appendQuery = (url, key, value) => {
    var options = key
    if (typeof options === 'string') {
        options = {}
        options[key] = value
    }
    options = $.param(options)
    if (url.includes('?')) {
        url += '&' + options
    } else {
        url += '?' + options
    }
    return url
}
/**
 * @description 在 source 包括 need
 * @param {String}  获取当前起止时间 date:当天  week：本周 month ：本月 year：本年
 * @returns {Object} startTime: 开始时间 endTime 结束时间  (时间戳)
 */

export const thisDate = (type = 'date', data = dayjs()) => {
    return {
        startTime: Number(
            dayjs(data)
                .startOf(type)
                .valueOf()
                .toString()
                .slice(0, 10)
        ),
        endTime: Number(
            dayjs(data)
                .endOf(type)
                .valueOf()
                .toString()
                .slice(0, 10)
        )
    }
}
/**
 * 格式时间为指定格式
 * @param {Object} time 10位时间戳
 * @param {Object} template 格式化的模板(年YYYY月MM日DD时hh分mm秒ss)
 */
export const formatTimeTemplate = (time, template) => {
    if (time && time > 0) {
        return dayjs(time * 1000).format(template)
    } else {
        return '暂无'
    }
}
/**
 * 获取时间日的起始
 * @param {Date} date 日期
 */
export const toDayStart = date => {
    return Math.floor(
        dayjs(date)
            .startOf('date')
            .toDate()
            .getTime() / 1000
    )
}
/**
 * 获取时间日的结束
 * @param {Date} date 日期
 */
export const toDayEnd = date => {
    return Math.floor(
        dayjs(date)
            .endOf('date')
            .toDate()
            .getTime() / 1000
    )
}
/**
 * 减少时间
 * @param {Number} time 10位时间戳基础量
 * @param {Number} num 减少的时间量
 * @param {String} template 减少的时间类型(年y月M周w天d小时h分钟m秒s毫秒ms)
 */
export const beforeTime = (time, num, template) => {
    return Math.floor(
        dayjs(time * 1000)
            .subtract(num, template)
            .toDate()
            .getTime() / 1000
    )
}
/**
 * 增加时间
 * @param {Number} time 10位时间戳基础量
 * @param {Number} num 增加的时间量
 * @param {String} template 增加的时间类型(年y月M周w天d小时h分钟m秒s毫秒ms)
 */
export const afterTime = (time, num, template) => {
    return Math.floor(
        dayjs(time * 1000)
            .add(num, template)
            .toDate()
            .getTime() / 1000
    )
}

/**
 * 表格action 添加 divider
 * @param {Array} list 10位时间戳基础量
 */
export const tableActions = list => {
    return list.reduce((pre, cur) => {
        console.log(pre)

        return pre.length
            ? [...pre, <Divider direction="vertical"></Divider>, cur]
            : [...pre, cur]
    }, [])
}
